#include <iostream>
#include "Heuristic.h"
#include "Arbiter.h"


Move::Move()
: _x(0), _y(0)
{
}

Move::Move(short unsigned x, short unsigned y)
{
	this->_x = x;
	this->_y = y;
}

Move::~Move()
{
}

Move::Move(const Move &m)
{
	this->_x = m._x;
	this->_y = m._y;
}

Move	&			Move::operator=(const Move &m)
{
	if(this != &m)
	{
		this->_x = m._x;
		this->_y = m._y;
	}
	return (*this);
}

void				Move::GetCoordinates(unsigned short & x, unsigned short & y)
{
	x = this->_x;
	y = this->_y;
}

void				Move::SetCoordinates(unsigned short & x, unsigned short & y)
{
	this->_x = x;
	this->_y = y;
}

// < ------------------------------------------------------------ >

Heuristic::Heuristic()
	:_cases(NULL), _moveCost(0), _moveCoordinates(0,0)
{
}

Heuristic::~Heuristic()
{
}

const char	Heuristic::Ctrl(const unsigned short x, const unsigned short y)
{
	const char error = 'e';
	if (x >= _cases->Width || x < 0 || y >= _cases->Height || y < 0) return (error);
	return (GET_COLOR(_cases->Cases[y][x]));
}

void		Heuristic::SetAdvColor(const char color)
{
	_color = color;
	_advcolor = (_color == COLOR_BLACK) ? (COLOR_WHITE) : (COLOR_BLACK);
	_nonecolor = COLOR_NONE;
}

void		Heuristic::InitContext(Board* cases, const Move & move, const char color)
{
	_cases = cases;
	_moveCoordinates = move;
	this->SetAdvColor(color);
}


/*
** Cost = 50
[a] x [ ]		OR	[ ] x [a]

[a]		[ ]		[a]	[ ]			[a]	 [ ]
 x		 x           x   x		    x     x
[ ]		[a]		    [ ]  [a]    [ ]	 [a]

*/
void		Heuristic::OneThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _nonecolor) this->_moveCost += 50;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _nonecolor) this->_moveCost += 50;
}

/*
** Cost = 125 - 250
[ ] x x o	 OR  o x x [ ]

 o     [ ]			o	[]					o    []
 x      x		OR   x      x		OR    x     x
 x      x				x      x        x     x
[ ]     o					[]     o []    o
*/
void		Heuristic::TwoBlockThreatSearch() 
{
	unsigned short x = 0, y = 0;

	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _color) this->_moveCost += 1000;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _color) this->_moveCost += 1000;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _color) this->_moveCost += 1000;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _color) this->_moveCost += 1000;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _color) this->_moveCost += 1000;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _color) this->_moveCost += 1000;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _color) this->_moveCost += 1000;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _color) this->_moveCost += 1000;

	if (Ctrl(x + 1, y) == _color && Ctrl(x + 2, y) == _color && Ctrl(x + 3, y) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x - 1, y) == _color && Ctrl(x - 2, y) == _color && Ctrl(x - 3, y) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x, y - 1) == _color && Ctrl(x, y - 2) == _color && Ctrl(x, y - 3) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x, y + 1) == _color && Ctrl(x, y + 2) == _color && Ctrl(x, y + 3) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x - 1, y - 1) == _color && Ctrl(x - 2, y - 2) == _color && Ctrl(x - 3, y - 3) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x + 1, y + 1) == _color && Ctrl(x + 2, y + 2) == _color && Ctrl(x + 3, y + 3) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x + 1, y - 1) == _color && Ctrl(x + 2, y - 2) == _color && Ctrl(x + 3, y - 3) == _advcolor) this->_moveCost += 50;
	if (Ctrl(x - 1, y + 1) == _color && Ctrl(x - 2, y + 2) == _color && Ctrl(x - 3, y + 3) == _advcolor) this->_moveCost += 50;
}

/*
** Cost = 250
[] x x []		OR	[] x x []

[ ]		[ ]		[]	[]			[]	[]
 x	OR	 x	OR     x   x	OR	    x    x
 x		 x           x   x		  x     x
[ ]		[ ]		    []  []    []	[]
*/
void		Heuristic::TwoFreeThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _nonecolor) this->_moveCost += 250;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _nonecolor) this->_moveCost += 250;
}

/*
** Cost 250

x [a] x [] x               x [ ] x [a] x

 x	 x		x      x                     x      x
[a] [ ]      [a]    [ ]               [a]    [ ]
 x   x          x      x             x      x
[ ] [a]          [ ]    [a]       [ ]    [a]
 x   x              x      x    x      x

*/
void			Heuristic::TwoOpenThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);

	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _nonecolor && Ctrl(x + 3, y) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _nonecolor && Ctrl(x - 3, y) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _nonecolor && Ctrl(x, y + 3) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _nonecolor && Ctrl(x, y - 3) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _nonecolor && Ctrl(x + 3, y + 3) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _nonecolor && Ctrl(x - 3, y - 3) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _nonecolor && Ctrl(x - 3, y - 3) == _advcolor) this->_moveCost += 250;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _nonecolor && Ctrl(x + 3, y - 3) == _advcolor) this->_moveCost += 250;

	//if (Ctrl(x - 1, y) == _advcolor && Ctrl(x + 1, y) == _advcolor) this->_moveCost += 250;
	//if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y + 1) == _advcolor) this->_moveCost += 250;
	//if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x - 1, y - 1) == _advcolor) this->_moveCost += 250;
	//if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x + 1, y - 1) == _advcolor) this->_moveCost += 250;
}

/*
** Cost 1000
[] x x [a] x []	OR	  [] x [a] x x []

[ ]	[ ]		[]	[]				[]	 []
 x	 x		  x    x			    x     x
 x	[a]	OR	   x    [a]	OR	   x   [a]
[a]	 x		    [a]    x		[a] 	 x
 x	 x			  x	  x	    x    x
[ ]	[ ]			   []   []  []	  []

*/
void		Heuristic::ThreeOpenThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _nonecolor && Ctrl(x - 1, y) == _advcolor &&  Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _nonecolor) this->_moveCost += 1000;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _nonecolor && Ctrl(x + 1, y) == _advcolor &&  Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _nonecolor) this->_moveCost += 1000;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _nonecolor && Ctrl(x, y - 1) == _advcolor &&  Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _nonecolor)	this->_moveCost += 1000;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _nonecolor && Ctrl(x, y + 1) == _advcolor &&  Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _nonecolor)	this->_moveCost += 1000;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _nonecolor && Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2,y - 2) == _advcolor && Ctrl(x - 3,y - 3) == _nonecolor)	this->_moveCost += 1000;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _nonecolor && Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3,y + 3) == _nonecolor)	this->_moveCost += 1000;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _nonecolor && Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _nonecolor)	this->_moveCost += 1000;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _nonecolor && Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _nonecolor)	this->_moveCost += 1000;
}

/*
** Cost = 2 000
o [a] x x x []		OR	  [] x x x [a] o

 o	 [ ]		o	[ ]							 o	  [ ]
[a]   x			[a]	   x					  [a]    x
 x    x            x    x					x      x
 x    x		OR	     x     x		OR    x      x
 x	 [a]				x	  [a]	    x	 [a]
[ ]   o					 [ ]	o	 [ ]   o

*/
void		Heuristic::ThreeOpenBlockSideOneThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x - 1, y) == _color && Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x + 1, y) == _color && Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x, y - 1) == _color && Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x, y + 1) == _color && Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x - 1, y - 1) == _color && Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor && Ctrl(x + 4, y + 4) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x + 1, y + 1) == _color && Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor && Ctrl(x - 4, y - 4) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x + 1, y - 1) == _color  && Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor && Ctrl(x - 4, y + 4) == _nonecolor) this->_moveCost += 2000;
	if (Ctrl(x - 1, y + 1) == _color  && Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor && Ctrl(x + 4, y - 4) == _nonecolor) this->_moveCost += 2000;
}

/*
** Cost = 2 500
o [ ] x x x [b]		OR	  [b] x x x [ ] o

 o	[b]		o	[b]							   o    [b]
[ ]   x		 [ ]   x					  [ ]      x
 x    x        x    x                    x      x
 x    x	OR	     x     x	OR        x       x
 x	[ ]             x	[ ]	        x     [ ]
[b]   o				[b]	   o    [b]	    o

*/
void		Heuristic::ThreeOpenBlockSideTwoThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _nonecolor && Ctrl(x - 5, y) == _color) this->_moveCost += 2500;
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _nonecolor && Ctrl(x + 5, y) == _color) this->_moveCost += 2500;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _nonecolor && Ctrl(x, y + 5) == _color) this->_moveCost += 2500;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _nonecolor && Ctrl(x, y - 5) == _color) this->_moveCost += 2500;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor  && Ctrl(x - 4, y - 4) == _nonecolor && Ctrl(x - 5, y - 5) == _color)	this->_moveCost += 2500;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor  && Ctrl(x + 4, y + 4) == _nonecolor && Ctrl(x + 5, y + 5) == _color)	this->_moveCost += 2500;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor  && Ctrl(x + 4, y - 4) == _nonecolor && Ctrl(x + 5, y - 5) == _color)	this->_moveCost += 2500;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor  && Ctrl(x - 4, y + 4) == _nonecolor && Ctrl(x - 5, y + 5) == _color)	this->_moveCost += 2500;
}

/*
** Cost = 7 500
[] x x x o	OR	 o x x x []

 o     [ ]	        o	[]				o    []
 x      x		OR   x    x		OR	   x    x
 x      x			  x	   x		  x	   x
 x      x			   x     x      x     x
[ ]     o			    []     o  []     o
*/
void		Heuristic::ThreeBlockThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _color) this->_moveCost += 7500;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _color) this->_moveCost += 7500;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _color) this->_moveCost += 7500;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _color) this->_moveCost += 7500;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor && Ctrl(x - 4, y - 4) == _color) this->_moveCost += 7500;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor && Ctrl(x + 4, y + 4) == _color) this->_moveCost += 7500;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor && Ctrl(x - 4, y + 4) == _color) this->_moveCost += 7500;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor && Ctrl(x + 4, y - 4) == _color) this->_moveCost += 7500;
}

/*
** Cost = 8000
[a] x x x []	OR	[] x x x [a]

[a] [ ]		[a]	[ ]				 [a]	[ ]
 x   x		  x     x			    x    x
 x   x	OR	    x	x	OR	  x     x
 x   x			 x	  x		x	x
[ ] [a]			  [ ]   [a]  [ ] [a]
*/
void		Heuristic::ThreeFreeThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor && Ctrl(x + 4, y + 4) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor && Ctrl(x - 4, y - 4) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor && Ctrl(x - 4, y + 4) == _nonecolor) this->_moveCost += 8000;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor && Ctrl(x + 4, y - 4) == _nonecolor) this->_moveCost += 8000;
}

/*
** Cost = 1 000 000
[] x x x x o	OR	 o x x x x []

 o     [ ]	      o    [ ]				      o    [ ]
 x      x          x     x                  x     x
 x      x		OR  x     x		OR	      x     x
 x	    x			 x	   x		    x	  x
 x      x			  x     x        x     x
[ ]     o			   []    o     []    o
*/
void		Heuristic::FourBlockThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _advcolor && Ctrl(x + 5, y) == _color) this->_moveCost += 1000000;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _advcolor && Ctrl(x - 5, y) == _color) this->_moveCost += 1000000;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _advcolor && Ctrl(x, y + 5) == _color) this->_moveCost += 1000000;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _advcolor && Ctrl(x, y - 5) == _color) this->_moveCost += 1000000;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor && Ctrl(x + 4, y + 4) == _advcolor && Ctrl(x + 5, y + 5) == _color) this->_moveCost += 1000000;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor && Ctrl(x - 4, y - 4) == _advcolor && Ctrl(x - 5, y - 5) == _color) this->_moveCost += 1000000;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor && Ctrl(x + 4, y - 4) == _advcolor && Ctrl(x + 5, y - 5) == _color) this->_moveCost += 1000000;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor && Ctrl(x - 4, y + 4) == _advcolor && Ctrl(x - 5, y + 5) == _color) this->_moveCost += 1000000;
}

/*
** Cost = 2 000 000
[a] x x x x []		OR	[] x x x x [a]

[a] [ ]	   [a]  [ ]				      [a]   [ ]
 x   x		x	 x				     x	  x
 x   x		  x   x			       x    x
 x   x	OR	    x	x	OR	     x    x
 x   x			 x	  x		   x	x
[ ] [a]			  [ ]   [a]  [ ] [a]
*/
void		Heuristic::FourFreeThreatSearch()
{
	unsigned short x = 0, y = 0;
	
	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _advcolor && Ctrl(x + 5, y) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x + 1, y) == _advcolor && Ctrl(x + 2, y) == _advcolor && Ctrl(x + 3, y) == _advcolor && Ctrl(x + 4, y) == _advcolor && Ctrl(x - 1, y) == _nonecolor) this->_moveCost += 2000000;//
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _advcolor && Ctrl(x - 5, y) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x - 1, y) == _advcolor && Ctrl(x - 2, y) == _advcolor && Ctrl(x - 3, y) == _advcolor && Ctrl(x - 4, y) == _advcolor && Ctrl(x + 1, y) == _nonecolor) this->_moveCost += 2000000;//
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _advcolor && Ctrl(x, y + 5) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x, y + 1) == _advcolor && Ctrl(x, y + 2) == _advcolor && Ctrl(x, y + 3) == _advcolor && Ctrl(x, y + 4) == _advcolor && Ctrl(x, y - 1) == _nonecolor) this->_moveCost += 2000000;//
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _advcolor && Ctrl(x, y - 5) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x, y - 1) == _advcolor && Ctrl(x, y - 2) == _advcolor && Ctrl(x, y - 3) == _advcolor && Ctrl(x, y - 4) == _advcolor && Ctrl(x, y + 1) == _nonecolor) this->_moveCost += 2000000;//

	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor && Ctrl(x + 4, y + 4) == _advcolor && Ctrl(x + 5, y + 5) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x + 1, y + 1) == _advcolor && Ctrl(x + 2, y + 2) == _advcolor && Ctrl(x + 3, y + 3) == _advcolor && Ctrl(x + 4, y + 4) == _advcolor && Ctrl(x - 1, y - 1) == _nonecolor) this->_moveCost += 2000000;//
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor && Ctrl(x - 4, y - 4) == _advcolor && Ctrl(x - 5, y - 5) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x - 1, y - 1) == _advcolor && Ctrl(x - 2, y - 2) == _advcolor && Ctrl(x - 3, y - 3) == _advcolor && Ctrl(x - 4, y - 4) == _advcolor && Ctrl(x + 1, y + 1) == _nonecolor) this->_moveCost += 2000000;//
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor && Ctrl(x - 4, y + 4) == _advcolor && Ctrl(x - 5, y + 5) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x - 1, y + 1) == _advcolor && Ctrl(x - 2, y + 2) == _advcolor && Ctrl(x - 3, y + 3) == _advcolor && Ctrl(x - 4, y + 4) == _advcolor && Ctrl(x + 1, y - 1) == _nonecolor) this->_moveCost += 2000000;//
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor && Ctrl(x + 4, y - 4) == _advcolor && Ctrl(x + 5, y - 5) == _nonecolor) this->_moveCost += 2000000;
	if (Ctrl(x + 1, y - 1) == _advcolor && Ctrl(x + 2, y - 2) == _advcolor && Ctrl(x + 3, y - 3) == _advcolor && Ctrl(x + 4, y - 4) == _advcolor && Ctrl(x - 1, y + 1) == _nonecolor) this->_moveCost += 2000000;//
}


bool		Heuristic::LookVertically()
{
	unsigned short	x = 0, y = 0;
	bool			res = false;
	const char		color = '0';

	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x, y + 1) == color && Ctrl(x, y + 2) == color && (Ctrl(x, y - 1) == _nonecolor || Ctrl(x, y + 3) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x, y - 1) == color && Ctrl(x, y - 2) == color && (Ctrl(x, y + 1) == _nonecolor || Ctrl(x, y - 3) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x, y + 1) == color && Ctrl(x, y + 2) == color && Ctrl(x, y + 3) == color && (Ctrl(x, y - 1) == _nonecolor || Ctrl(x, y + 4) == _nonecolor)) res = true;
	if (Ctrl(x, y - 1) == color && Ctrl(x, y - 2) == color && Ctrl(x, y - 3) == color && (Ctrl(x, y + 1) == _nonecolor || Ctrl(x, y - 4) == _nonecolor)) res = true;
	return res;
}

bool		Heuristic::LookHorizontally()
{
	unsigned short	x = 0, y = 0;
	bool			res = false;
	const char		color = '0';

	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y) == color && Ctrl(x + 2, y) == color && (Ctrl(x - 1, y) == _nonecolor || Ctrl(x + 3, y) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x - 1, y) == color && Ctrl(x - 2, y) == color && (Ctrl(x + 1, y) == _nonecolor || Ctrl(x - 3, y) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x + 1, y) == color && Ctrl(x + 2, y) == color && Ctrl(x + 3, y) == color && (Ctrl(x - 1, y) == _nonecolor || Ctrl(x + 4, y) == _nonecolor)) res = true;
	if (Ctrl(x - 1, y) == color && Ctrl(x - 2, y) == color && Ctrl(x - 3, y) == color && (Ctrl(x + 1, y) == _nonecolor || Ctrl(x - 4, y) == _nonecolor)) res = true;
	return res;
}

bool		Heuristic::LookOnDiagonalLeft()
{
	unsigned short	x = 0, y = 0;
	bool			res = false;
	const char		color = '0';

	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x - 1, y - 1) == color && Ctrl(x - 2, y - 2) == color && (Ctrl(x - 3, y - 3) == _nonecolor || Ctrl(x + 1, y + 1) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x + 1, y + 1) == color && Ctrl(x + 2, y + 2) == color && (Ctrl(x + 3, y + 3) == _nonecolor || Ctrl(x - 1, y - 1) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x - 1, y - 1) == color && Ctrl(x - 2, y - 2) == color && Ctrl(x - 3, y - 3) == color && (Ctrl(x - 4, y - 4) == _nonecolor || Ctrl(x + 1, y + 1) == _nonecolor)) res = true;
	if (Ctrl(x + 1, y + 1) == color && Ctrl(x + 2, y + 2) == color && Ctrl(x + 3, y + 3) == color && (Ctrl(x + 4, y + 4) == _nonecolor || Ctrl(x - 1, y - 1) == _nonecolor)) res = true;
	return res;
}

bool		Heuristic::LookOnDiagonalRight()
{
	unsigned short	x = 0, y = 0;
	bool			res = false;
	const char		color = '0';

	this->_moveCoordinates.GetCoordinates(x, y);
	if (Ctrl(x + 1, y - 1) == color && Ctrl(x + 2, y - 2) == color && (Ctrl(x + 3, y - 3) == _nonecolor || Ctrl(x - 1, y + 1) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x - 1, y + 1) == color && Ctrl(x - 2, y + 2) == color && (Ctrl(x - 3, y + 3) == _nonecolor || Ctrl(x + 1, y - 1) == _nonecolor)) this->_moveCost += 1400;
	if (Ctrl(x + 1, y - 1) == color && Ctrl(x + 2, y - 2) == color && Ctrl(x + 3, y - 3) == color && (Ctrl(x + 4, y - 4) == _nonecolor || Ctrl(x - 1, y + 1) == _nonecolor)) res = true;
	if (Ctrl(x - 1, y + 1) == color && Ctrl(x - 2, y + 2) == color && Ctrl(x - 3, y + 3) == color && (Ctrl(x - 4, y + 4) == _nonecolor || Ctrl(x + 1, y - 1) == _nonecolor)) res = true;
	return res;
}

void		Heuristic::HuntFourAlignedPieces()
{
	unsigned short	x = 0, y = 0;
	const char		color = '0';

	static Tab2			mytab[] = 
	{
		{ &Heuristic::LookVertically },
		{ &Heuristic::LookHorizontally },
		{ &Heuristic::LookOnDiagonalLeft },
		{ &Heuristic::LookOnDiagonalRight },
		{0}
	};
	this->_moveCoordinates.GetCoordinates(x, y);
	if (GET_COLOR(_cases->Cases[y][x]) == color)
	{
		for (int k = 0; mytab[k].M_Ptr2 != 0 ; ++k)
		{
			if ((this->*(mytab[k].M_Ptr2))() == true)
			{ 
				this->_moveCost += 15000;
				return;
			}
		}
	}
}

const int	Heuristic::GetMoveValue(Board* cases, const Move & move, const char color)
{
	unsigned short x = 0, y = 0;
	Arbiter& arbiter = Gomoku::Instance().Arbiter;

	this->InitContext(cases, move, color);
	this->_moveCoordinates.GetCoordinates(x, y);
	if (arbiter.IsFivePieceAligned(this->_cases->Cases[y][x], *_cases) == true)
	{
		this->_moveCost = 4000000;
		return (this->_moveCost);
	}
	static Tab		mytab[] =
	{
		{ &Heuristic::OneThreatSearch },
		{ &Heuristic::TwoBlockThreatSearch },
		{ &Heuristic::TwoFreeThreatSearch },
		{ &Heuristic::TwoOpenThreatSearch },
		{ &Heuristic::ThreeOpenThreatSearch },
		{ &Heuristic::ThreeOpenBlockSideOneThreatSearch },
		{ &Heuristic::ThreeOpenBlockSideTwoThreatSearch },
		{ &Heuristic::ThreeBlockThreatSearch },
		{ &Heuristic::ThreeFreeThreatSearch },
		{ &Heuristic::FourBlockThreatSearch },
		{ &Heuristic::FourFreeThreatSearch },
		{ 0 }
	};
	for (int i = 0; mytab[i].M_Ptr != 0 ; ++i)
	{
		(this->*(mytab[i].M_Ptr))();
	}
	this->HuntFourAlignedPieces();
	return (this->_moveCost);
}